package com.dg.acb.utils.xml;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.text.TextUtils;
import android.util.Xml;
/**
 *  XML解析读取
 * @author hjwang2
 * @version 1.0
 * @since 2015-8-20
 */
public class XmlParserCtrl implements IXmlCtrl{
    private final String mHomeTag;
    private XmlPullParser mXmlPullParser;
    private InputStream mInStream;

    public XmlParserCtrl(String xmlFilePath, String homeTag) throws IOException{
        this.mInStream = new FileInputStream(xmlFilePath);
        this.mHomeTag = homeTag;
    }

    public XmlParserCtrl(InputStream inputStream, String homeTag) {
        this.mInStream = Objects.requireNonNull(inputStream);
        this.mHomeTag = homeTag;
    }

    public synchronized boolean startParser(){
        if (mXmlPullParser != null) {
            throw new IllegalArgumentException("有正在进行的操作未finish");
        }
        if (mInStream == null) {
            throw new IllegalArgumentException("解析操作已停止，不能再执行");
        }
        try {
            mXmlPullParser = Xml.newPullParser();
            //设置输入流 并指明编码方式
            mXmlPullParser.setInput(mInStream, ENCODING);
            int eventType = mXmlPullParser.getEventType();
            if (eventType != XmlPullParser.END_DOCUMENT) {
                if (!TextUtils.isEmpty(mHomeTag)) {
                    moveToNextStartTag(mHomeTag);
                }
                moveToNextStartTag(null);
            }
            return true;
        } catch (XmlPullParserException e) {
            e.printStackTrace();
            finishParser();
        } catch (IOException e) {
            e.printStackTrace();
            finishParser();
        }
        return false;
    }

    public synchronized void finishParser(){
        try {
            if (mInStream != null) {
                mInStream.close();
            }
            mInStream = null;
            mXmlPullParser = null;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean skipNearEndTag(String tagName)
            throws XmlPullParserException, IOException {
        int eventType = mXmlPullParser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            eventType = mXmlPullParser.next();
            if (eventType == XmlPullParser.END_TAG &&
                    (TextUtils.isEmpty(tagName)
                            || mXmlPullParser.getName().equals(tagName))) {
                return moveToNextStartTag(null);
            }
        }
        return false;
    }

    public boolean moveToNextStartTag(String tagName)
            throws XmlPullParserException, IOException {
        int eventType = mXmlPullParser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            eventType = mXmlPullParser.next();
            if (eventType == XmlPullParser.START_TAG &&
                    (TextUtils.isEmpty(tagName)
                            || mXmlPullParser.getName().equals(tagName))) {
                return true;
            }
        }
        return false;
    }

    public XmlTag parseTagAndMoveToNext()
            throws IOException, XmlPullParserException {
        XmlTag homeTag = null;
        int eventType = mXmlPullParser.getEventType();
        if (eventType != XmlPullParser.START_TAG && !moveToNextStartTag(null)) {
            return homeTag;
        }
        String name = mXmlPullParser.getName();
        int attributeCount = mXmlPullParser.getAttributeCount();
        String[] attributeNames = new String[attributeCount];
        String[] attributeValues = new String[attributeCount];
        for (int i = 0; i < attributeCount; i++) {
            attributeNames[i] = mXmlPullParser.getAttributeName(i);
            attributeValues[i] = mXmlPullParser.getAttributeValue(i);
        }
        if (!"if".equals(name)) {
            eventType = mXmlPullParser.next();
            if (eventType == XmlPullParser.END_TAG) {
                homeTag = NBXmlTag.obtain(name, null);
            } else {
                String text = null;
                if (eventType == XmlPullParser.TEXT) {
                    text = mXmlPullParser.getText();
                    eventType = mXmlPullParser.next();
                }
                if (eventType == XmlPullParser.START_TAG) {
                    homeTag = NBXmlTag.obtain(name);
                    while (eventType != XmlPullParser.END_TAG
                            && !name.equals(mXmlPullParser.getName())) {
                        homeTag.addSubTag(parseTagAndMoveToNext());
                    }
                } else {
                    homeTag = NBXmlTag.obtain(name, text);
                }
            }
        }else {
            homeTag = NBXmlTag.obtain(name);
        }
        for (int i = 0; i < attributeCount; i++) {
            homeTag.addAttribute(attributeNames[i], attributeValues[i]);
        }
        nextTag();
        return homeTag;
    }

    private void nextTag() throws XmlPullParserException, IOException {
        int type = mXmlPullParser.next();
        if (type == XmlPullParser.TEXT) {
            mXmlPullParser.next();
        }
    }
}